package com.im.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.im.entity.ImSession;
import com.im.entity.dto.SessionDTO;
import com.im.mapper.ImSessionMapper;
import com.im.service.IImSessionService;
import com.im.utils.BeanCopyUtils;
import com.im.utils.Redis.RedisIdGenerator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author im
 * @since 2025-01-30
 */
@Slf4j
@Service
public class ImSessionServiceImpl extends ServiceImpl<ImSessionMapper, ImSession> implements IImSessionService {

    @Autowired
    private RedisIdGenerator redisIdGenerator;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private RedisSessionService redisSessionService;
    /**
     * 返回会话id
     * @param privateSessionDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long createPrivateSession(SessionDTO privateSessionDTO) {
        if (privateSessionDTO.getType()==2) {
            throw new RuntimeException("不要通过单聊的方式创建群聊会话");
        }
        //需要先判断当前用户和目标用户是否已经存在会话
        ImSession imSession = this.baseMapper.selectOne(new LambdaQueryWrapper<ImSession>().select(ImSession::getSessionId)
                .nested(query ->
                        query.eq(ImSession::getUserId, privateSessionDTO.getUserId()).eq(ImSession::getTargetId, privateSessionDTO.getTargetId()))
                .or(nested ->
                        nested.eq(ImSession::getUserId, privateSessionDTO.getTargetId()).eq(ImSession::getTargetId, privateSessionDTO.getUserId())
                ));
        //如果存在，则直接返回会话id
        if (imSession!= null) {
            return imSession.getSessionId();
        }
        //如果不存在，则生成会话id
        Long sessionId = redisIdGenerator.generateSessionId();
        //创建会话
        ImSession privateSession = BeanCopyUtils.copyObject(privateSessionDTO, ImSession.class);
        privateSession.setSessionId(sessionId);
        this.save(privateSession);
        //将当前会话可以存储到双方redis的列表中
        redisSessionService.addPrivateSession(privateSessionDTO.getUserId(),privateSession.getTargetId(),sessionId);

        return sessionId;
    }

    /**
     * 获取用户会话列表
     * @param userId
     * @return
     */
    @Override
    public List<ImSession> getSessionList(Integer userId) {
        //查询当前用户的会话列表
        List<Integer> sessionListForUser = redisSessionService.getSessionListForUser(userId);
        //如果没有会话列表 查询数据库中
        if (sessionListForUser == null || sessionListForUser.size() == 0) {
            log.info("用户{}的会话列表为空或mysql查询未接入",userId);

        }
        //根据会话列表查询数据库中的会话信息
        return this.baseMapper.selectList(new LambdaQueryWrapper<ImSession>().in(ImSession::getSessionId, sessionListForUser));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long createGroupSession(SessionDTO sessionDTO) {
        //生成会话id
        if (sessionDTO.getType()==1) {
            throw new RuntimeException("不要通过群聊的方式创建单聊会话");
        }
        //查看当前群聊id是否已经存在
        ImSession imSession = this.baseMapper.selectOne(new LambdaQueryWrapper<ImSession>()
                .select(ImSession::getSessionId)
                .eq(ImSession::getTargetId, sessionDTO.getTargetId()));
        if (imSession != null) {
            return imSession.getSessionId();
        }
        //生成会话id
        Long sessionId = redisIdGenerator.generateSessionId();
        ImSession groupSession = BeanCopyUtils.copyObject(sessionDTO, ImSession.class);
        groupSession.setSessionId(sessionId);
        // TODO: Redis插入群聊Session
        this.baseMapper.insert(groupSession);
        return sessionId;
    }
}
